﻿using System;
using System.Collections;
using System.Collections.Generic;
#if (LINQ)
using System.Linq;
#endif
using System.Text;

using System.ComponentModel;

namespace Robin.LightNing.Core
{
    /// <summary>
    /// 数据绑定的时候使用
    /// </summary>
    public delegate object DynamicGetValue(object component);

    /// <summary>
    /// 数据绑定的时候使用
    /// </summary>
    public delegate void DynamicSetValue(object component, object newValue);

    /// <summary>
    /// 属性描述器，数据绑定的时候使用
    /// </summary>
    public class rbPropertyDescriptor : PropertyDescriptor
    {
        private PropertyDescriptor _trueDescriptor;
        private rbEntity _entity;
        private rbEntity _containedEntity;
        /// <summary>
        /// 
        /// </summary>
        protected Type m_componentType;
        /// <summary>
        /// 
        /// </summary>
        protected Type m_propertyType;
        /// <summary>
        /// 
        /// </summary>
        protected DynamicGetValue m_getDelegate;
        /// <summary>
        /// 
        /// </summary>
        protected DynamicSetValue m_setDelegate;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="componentType"></param>
        /// <param name="name"></param>
        /// <param name="propertyType"></param>
        /// <param name="getDelegate"></param>
        /// <param name="setDelegate"></param>
        public rbPropertyDescriptor(Type componentType, string name, Type propertyType, DynamicGetValue getDelegate, DynamicSetValue setDelegate)
            : base(name, null)
        {
            m_componentType = componentType;
            m_propertyType = propertyType;
            m_getDelegate = getDelegate;
            m_setDelegate = setDelegate;
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="name"></param>
        /// <param name="propertyType"></param>
        /// <param name="containedEntity"></param>
        public rbPropertyDescriptor(rbEntity entity, string name, Type propertyType, rbEntity containedEntity)
            : base(name, null)
        {
            this._entity = entity;
            this.m_propertyType = propertyType;
            this._containedEntity = containedEntity;
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="name"></param>
        /// <param name="propertyType"></param>
        public rbPropertyDescriptor(rbEntity entity, string name, Type propertyType)
            : base(name, null)
        {
            this._entity = entity;
            this.m_propertyType = propertyType;
        }
        /// <summary>
        /// 指示重置组件是否会更改该组件的值
        /// </summary>
        /// <param name="component"></param>
        /// <returns></returns>
        public override bool CanResetValue(object component)
        {
            return false;
        }
        /// <summary>
        /// 组件类型
        /// </summary>
        public override Type ComponentType
        {
            get
            {
                if (this._containedEntity != null)
                {
                    return this._containedEntity.GetType();
                }
                else
                {
                    return m_propertyType;
                }
            }
        }
        /// <summary>
        /// 指示该属性是否是只读的
        /// </summary>
        public override bool IsReadOnly
        {
            get { return m_setDelegate == null; }
        }
        /// <summary>
        /// 获取属性的类型
        /// </summary>
        public override Type PropertyType
        {
            get { return m_propertyType; }
        }
        /// <summary>
        /// 重置组件属性的值
        /// </summary>
        /// <param name="component"></param>
        public override void ResetValue(object component)
        {

        }
        /// <summary>
        /// 返回组件上属性的当前值
        /// </summary>
        /// <param name="component"></param>
        /// <returns></returns>
        public override object GetValue(object component)
        {
            rbEntity obj = component as rbEntity;

            if (obj == null) return null;

            if (_trueDescriptor != null)
            {
                return this._trueDescriptor.GetValue(component);
            }
            else
            {
                object o = null;

                if (m_getDelegate != null)
                {
                    o = m_getDelegate(component);
                }
                else
                {
                    obj.currentValues.TryGetValue(this.Name, out o);
                }

                return o;
            }
        }
        /// <summary>
        /// 将组件的值设置为一个不同的值
        /// </summary>
        /// <param name="component"></param>
        /// <param name="value"></param>
        public override void SetValue(object component, object value)
        {
            rbEntity obj = component as rbEntity;

            if (obj == null) return;

            if (_trueDescriptor != null)
            {
                _trueDescriptor.SetValue(component, value);
            }
            else
            {
                if (obj != null)
                {
                    if (m_setDelegate != null)
                    {
                        m_setDelegate(obj, value);
                    }
                    else
                    {
                        obj.currentValues[this.Name] = value;
                        obj.OnPropertyChanged(this.Name);
                    }
                }
            }
        }
        /// <summary>
        /// 指示是否需要持久保存该属性的值
        /// </summary>
        /// <param name="component"></param>
        /// <returns></returns>
        public override bool ShouldSerializeValue(object component)
        {
            return true;
        }
        /// <summary>
        /// 包含的实体
        /// </summary>
        public rbEntity ContainedEntity
        {
            get { return _containedEntity; }
        }
        /// <summary>
        /// 
        /// </summary>
        public PropertyDescriptor TrueDescriptor
        {
            set { this._trueDescriptor = value; }
        }
    }
}
